package com.cljh.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.cljh.bean.Admin;
import com.cljh.bean.Path;
import com.cljh.bean.Role;
import com.cljh.bean.User;
import com.cljh.config.AuthAccess;
import com.cljh.controller.page.Code;
import com.cljh.controller.page.PageBean;
import com.cljh.controller.page.ProductPageBean;
import com.cljh.controller.page.Result;
import com.cljh.mapper.RoleMapper;
import com.cljh.mapper.RoleMenuMapper;
import com.cljh.service.AdminService;
import com.cljh.service.MenuService;
import com.cljh.service.RoleService;
import com.cljh.service.UserService;
import com.cljh.utils.CheckCodeUtil;
import com.cljh.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 登录和注册模块
 */
@RestController
@RequestMapping("/admins")
public class AdminController {
    @Autowired
    AdminService adminService;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    RoleMenuMapper menuMapper;
    @Autowired
    MenuService menuService;
    @Autowired
    UserService userService;
    @PostMapping
    public Result save(@RequestBody Admin admin) {
        String email = admin.getEmail();
        if (email!=null&&!"".equals(email)){
            User user1 = userService.selectByEmailCode(email);
            Admin admin1 = adminService.selectByEmailCode(email);
            if (user1!=null||admin1!=null){
                return new Result(Code.SAVE_ERR,null,"邮箱已经被注册过了");
            }
        }
        boolean save = adminService.save(admin);
        Integer code = save ? Code.SAVE_OK : Code.SAVE_ERR;
        String msg = save ? "添加成功" : "添加失败";
        return new Result(code, save, msg);
    }
    @AuthAccess
    //判断用户名是否存在
    @GetMapping("/{username}")
    public Result selectByUsername(@PathVariable String username) {
        Admin admin = new Admin();
        admin.setUsername(username);
        Admin admin1 = adminService.selectByUsername(admin);

        Integer code = admin1 != null ? Code.GET_OK : Code.GET_ERR;
        String msg = admin1 != null ? "查到信息" : "未查到信息";

        return new Result(code, admin1, msg);
    }
    //登录
    @AuthAccess
    @PostMapping("/login")
    public Result select(@RequestBody Admin admin,HttpServletRequest request) {
        Admin select = adminService.select(admin);
//        request.getServletContext().setAttribute("");
       if (select!=null){
           //设置token
           String s = TokenUtils.genToken(select.getUsername(), select.getPassword());
//        System.out.println(s);
           select.setToken(s);

           String role = select.getRole();
           int roleId=0;
           if (!"".equals(role)){
               Role role1 = roleMapper.selectByKey(role);
               roleId=role1.getId();
           }
           //当前对象所有的菜单id集合
           List<Integer> integers = menuMapper.selectByRoleId(roleId);
           //列出所有菜单
           List<Path> paths = menuService.selectAllPath();
//        System.out.println(paths);
           //筛选出来的菜单
           List<Path> roleMenus=new ArrayList<>();
           for (Path p : paths) {
               if(integers.contains(p.getId())){
                   roleMenus.add(p);
               }
               List<Path> children = p.getChildren();
//            //移除 children里面不在id的元素中
               children.removeIf(child->!integers.contains(child.getId()));
           }
           select.setMenus(roleMenus);
       }
        Integer code = select != null ? Code.GET_OK : Code.GET_ERR;
        String msg = select != null ? "查到信息" : "未查到信息";
        return new Result(code,select,msg);

    }
    //生成验证码
    @AuthAccess
    @GetMapping("/register/checkCode")
    public void CheckCode(HttpServletResponse response ,HttpServletRequest request) throws IOException {
        //调用code工具类 生成验证码
        ServletOutputStream outputStream = response.getOutputStream();
        String s = CheckCodeUtil.outputVerifyImage(100, 50, outputStream, 4);
        request.getServletContext().setAttribute("code",s);
        System.out.println("输入的"+s);

    }
    //修改
    @PutMapping
    public  Result upAdmin(@RequestBody Admin admin){
        boolean upd = adminService.upd(admin);
        Integer c = upd ? Code.UPDATE_OK : Code.UPDATE_ERR;
        String msg = upd ? "修改成功" : "修改失败";
        return new Result(c,upd,msg);
    }
    //修改
    @PutMapping("/upd/{password}/{id}")
    public  Result upAdmin1(@PathVariable String password,@PathVariable Integer id){
        boolean upd = false;
        if (!"".equals(password)&&id!=null){
            Admin admin = new Admin();
            admin.setId(id);
            admin.setPassword(password);
            upd= adminService.upd(admin);
        }
        Integer c = upd ? Code.UPDATE_OK : Code.UPDATE_ERR;
        String msg = upd ? "修改成功" : "修改失败";
        return new Result(c,upd,msg);
    }


    @GetMapping("/get")
    public Result selectProduct(@RequestParam Integer currentPage,
                                @RequestParam Integer pageSize,
                                @RequestParam(defaultValue = "") String username,
                                @RequestParam(defaultValue = "") String gender){
        Admin admin = new Admin();
        admin.setUsername(username);
        admin.setGender(gender);
        PageBean<Admin> productPageBean = adminService.selectAllByCondition(currentPage, pageSize, admin);
        Integer code=productPageBean !=null ? Code.GET_OK:Code.GET_ERR;
        String msg=productPageBean!=null ? "查询到信息":"未查询到信息";
        return new Result(code,productPageBean,msg);
    }


    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id){
        boolean delete = adminService.deleteId(id);
        Integer code=delete ? Code.DELETE_OK:Code.DELETE_ERR;
        String msg=delete ? "删除一个成功":"删除一个失败";
        return new Result(code,delete,msg);
    }

    @DeleteMapping("/deleteIds")
    public Result deleteByIds(@RequestBody List<Integer> ids){
        boolean b = adminService.deleteIds(ids);
        Integer code=b ? Code.DELETE_OK:Code.DELETE_ERR;
        String msg=b ? "删除成功":"删除失败";
        return new Result(code,b,msg);
    }

    @GetMapping("/get/{id}")
    public Result selectById(@PathVariable Integer id){
        Admin admin = adminService.selectById(id);
        Integer code=admin !=null ? Code.GET_OK:Code.GET_ERR;
        String msg=admin!=null ? "查询到信息":"未查询到信息";
        return new Result(code,admin,msg);
    }

    @GetMapping("/all")
    public Result selectAll(){
        List<Admin> admin = adminService.selectAll();
        Integer code=admin !=null ? Code.GET_OK:Code.GET_ERR;
        String msg=admin!=null ? "查询到信息":"未查询到信息";
        return new Result(code,admin,msg);
    }

    /**
     * 导出excel表格
     * @param response
     * @throws Exception
     */
    @AuthAccess
    @GetMapping("/export")
    public void export(HttpServletResponse response)throws Exception{
        //从数据库查询出所有数据
        List<Admin> list=adminService.selectAll();
        //通过工具创建writer 写出到磁盘路径
//        ExcelWriter writer= ExcelUtil.getWriter(filesUploadPath+"/用户信息.xlsx");
        //内存操作，写出到浏览器
        ExcelWriter writer= ExcelUtil.getWriter(true);
        //自定义标题别名
        writer.addHeaderAlias("id" ,"id");
        writer.addHeaderAlias("username" ,"用户名");
        writer.addHeaderAlias("password" ,"密码");
        writer.addHeaderAlias("nickname" ,"姓名");
        writer.addHeaderAlias("gender" ,"性别");
        writer.addHeaderAlias("phone" ,"电话号码");
        writer.addHeaderAlias("img" ,"照片");
        writer.addHeaderAlias("address" ,"地址");
        writer.addHeaderAlias("role" ,"角色");
        writer.addHeaderAlias("email" ,"邮箱");
        //一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list,true);
        //设置浏览器响应格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName= URLEncoder.encode("管理员信息表","UTF-8");
        response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");

        ServletOutputStream out =response.getOutputStream();
        writer.flush(out,true);
        out.close();
        writer.close();

    }

    /**
     * 导入excel
     * @param file
     */
    @AuthAccess
    @PostMapping("/import")
    public void importExcel(MultipartFile file) throws IOException, ParseException {
        System.out.println("文件为"+file);


        //1.第一种 头必须和实体(英文)一样
        //文件处理成io流
        InputStream in = file.getInputStream();
//        //io流给ExcelReader
        ExcelReader excelReader=ExcelUtil.getReader(in);
//        //读取数据且转化为list
//        List<ProductPageBean> list = excelReader.readAll(ProductPageBean.class);

        //2.第二种导入方式
//        忽略第一行头(第一行是中文的情况),直接读取表的内容
        List<List<Object>> list = excelReader.read(1);
        System.out.println(list);
//        List<Admin> adminList = CollUtil.newArrayList();
        List<Admin> adminList = new ArrayList<>();
        for (List<Object> row: list) {
            Admin admin = new Admin();
            admin.setUsername(row.get(0).toString());
            admin.setPassword(row.get(1).toString());
            admin.setNickname(row.get(2).toString());
            admin.setGender(row.get(3).toString());
            admin.setPhone(row.get(4).toString());
            admin.setImg(row.get(5).toString());
            admin.setAddress(row.get(6).toString());
            admin.setRole(row.get(7).toString());
            admin.setEmail(row.get(8).toString());
            System.out.println(admin);
            adminList.add(admin);
            System.out.println("adminlist:"+adminList);
//            ****类似一一对应****
        }
        //批量注册进数据库
        System.out.println("adminlist:"+adminList);
        adminService.saveAll(adminList);

    }


}
